package com.topcoder.commons.utils;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * This is a static helper class that provides methods for constructing
 * exception instances using reflection. It is used by ValidationUtility,
 * PropertiesUtility and JDBCUtility.
 * 
 * Thread Safety: This class is immutable and thread safe when array parameters
 * passed to it are used by the caller in thread safe manner.
 */
class ExceptionHelper {
	/**
	 * Empty private constructor.
	 * 
	 * Implementation Notes: Do nothing.
	 */
	private ExceptionHelper() {
	}

	/**
	 * Constructs an exception of the specified type with the given message.
	 * 
	 * Generic Parameters: T - the type of the exception to be created
	 * 
	 * Implementation Notes: 1. Constructor<T> constructor =
	 * exceptionClass.getConstructor(String.class); 2. T result =
	 * constructor.newInstance(message); 3. Return result.
	 * 
	 * @Title constructException
	 * @param message        the message
	 * @param exceptionClass the exception class
	 * @return : T the constructed exception instance (not null)
	 * @author lujie
	 * @throws Exception if any error occurred when using the reflection
	 */
	static <T extends Throwable> T constructException(Class<T> exceptionClass, String message) {
		Constructor<T> constructor = null;
		T result = null;
		try {
			constructor = exceptionClass.getConstructor(String.class);
			result = constructor.newInstance(message);
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return result;
	}

	/**
	 * * Constructs an exception of the specified type with the given message and
	 * cause.
	 * 
	 * Generic Parameters: T - the type of the exception to be created
	 * 
	 * Implementation Notes: 1. Constructor<T> constructor =
	 * exceptionClass.getConstructor(String.class, Throwable.class); 2. T result =
	 * constructor.newInstance(message, cause); 3. Return result.
	 * 
	 * Note: exceptions are populated without wrapping in this method.
	 * 
	 * @Title constructException
	 * @param message        the message
	 * @param cause          the exception cause
	 * @param exceptionClass the exception class
	 * @return : T the constructed exception instance (not null)
	 * @author lujie
	 * @throws Exception if any error occurred when using the reflection
	 */
	static <T extends Throwable> T constructException(Class<T> exceptionClass, String message, Throwable cause) {
		Constructor<T> constructor = null;
		T result = null;
		try {
			constructor = exceptionClass.getConstructor(String.class, Throwable.class);
			result = constructor.newInstance(message, cause);
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return result;
	}
}
